package org.dromara.wms.service;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.web.core.BaseService;
import org.dromara.wms.domain.WmsStock;
import org.dromara.wms.domain.WmsStockCheckLine;
import org.dromara.wms.domain.WmsStockLog;
import org.dromara.wms.mapper.WmsStockCheckLineMapper;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.dromara.wms.domain.WmsStockCheck;
import org.dromara.wms.mapper.WmsStockCheckMapper;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.Objects;

/**
 * 库存盘点Service业务层处理
 *
 * @author wenrui Su
 * @date 2024-05-03
 */
@RequiredArgsConstructor
@Service
public class WmsStockCheckService extends BaseService {

    private final WmsStockCheckMapper baseMapper;
    private final WmsStockCheckLineMapper lineMapper;
    private final WmsStockService stockService;
  private final WmsStockLogService wmsStockLogService;

    /**
     * 查询库存盘点
     */
    public WmsStockCheck queryById(Long id){
        return baseMapper.selectById(id);
    }

    /**
     * 查询库存盘点列表
     */
    public TableDataInfo<WmsStockCheck> queryPageList(WmsStockCheck bo, PageQuery pageQuery) {
      Page<WmsStockCheck> result = baseMapper.stockCheckList(pageQuery.build(),bo);
      return TableDataInfo.build(result);
    }

  /**
   * 查询库存子列表
   */
  public TableDataInfo<WmsStockCheckLine> queryPageLineList(WmsStockCheckLine bo, PageQuery pageQuery) {
    Page<WmsStockCheckLine> result = lineMapper.selectStockCheckLine(pageQuery.build(), bo);
    return TableDataInfo.build(result);
  }

  /**
   * 删除库存子列表
   */
  public boolean delLineList(Long lineId) {
    return lineMapper.deleteById(lineId) > 0;
  }

    /**
     * 查询库存盘点列表
     */
    public List<WmsStockCheck> queryList(WmsStockCheck bo) {
        LambdaQueryWrapper<WmsStockCheck> lqw = buildQueryWrapper(bo);
        return baseMapper.selectList(lqw);
    }

    private LambdaQueryWrapper<WmsStockCheck> buildQueryWrapper(WmsStockCheck bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<WmsStockCheck> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getWarehouseId() != null, WmsStockCheck::getWarehouseId, bo.getWarehouseId());
        lqw.eq(bo.getUserId() != null, WmsStockCheck::getUserId, bo.getUserId());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), WmsStockCheck::getStatus, bo.getStatus());
        return lqw;
    }

    /**
     * 新增库存盘点
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public Boolean insertByBo(WmsStockCheck bo) {
      validEntityBeforeSave(bo);
      boolean flag = baseMapper.insert(bo) > 0;
      //  新增子表
      List<WmsStockCheckLine> lineList = bo.getLine();
      for (WmsStockCheckLine line : lineList) {
        //判断相同库下有无相同产品的盘点，如果有，再判断其是否已经结束盘点，结束了再插入新盘点
        List<WmsStockCheckLine> checkLine = lineMapper.selectStockCheckLine(line);
        if (checkLine != null){
          for (WmsStockCheckLine i : checkLine){
            WmsStockCheck wmsStockCheck = baseMapper.selectById(i.getId());
            if (wmsStockCheck != null && !Objects.equals(wmsStockCheck.getStatus(), "0")){
              throw new RuntimeException("物品 "+i.getProductName()+" 已存在盘点数据，且未完成盘点，不可重复添加");
            }
          }
        }
          line.setId(bo.getId());
          this.insertLineByBo(line);
      }
        return flag;
    }

  /**
   * 新增子表
   */
  @Transactional(propagation = Propagation.REQUIRED)
  public void insertLineByBo(WmsStockCheckLine bo) {
    lineMapper.insert(bo);
  }

    /**
     * 修改库存盘点
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public Boolean updateByBo(WmsStockCheck bo) {
      validEntityBeforeSave(bo);
      boolean flag = baseMapper.updateById(bo) > 0;
      //  修改子表
      List<WmsStockCheckLine> lineList = bo.getLine();
      for (WmsStockCheckLine line : lineList) {
        if (line.getLineId()!=null){
          this.updateLineByBo(line);
        }else{
          line.setId(line.getId());
          this.insertLineByBo(line);
        }
      }
        return flag;
    }

  /**
   * 修改子表
   */
  @Transactional(propagation = Propagation.REQUIRED)
  public void updateLineByBo(WmsStockCheckLine bo) {
    LambdaUpdateWrapper<WmsStockCheckLine> lqw = updateWrapper(bo);
    lineMapper.update(lqw);
  }
  private LambdaUpdateWrapper<WmsStockCheckLine> updateWrapper (WmsStockCheckLine bo) {
    LambdaUpdateWrapper<WmsStockCheckLine> lqw = Wrappers.lambdaUpdate();
    lqw.eq(WmsStockCheckLine::getLineId, bo.getLineId());
    lqw.set(WmsStockCheckLine::getCheckQuantity, bo.getCheckQuantity());
    return lqw;
  }
  /**
   * 库存盘点 发送
   */
  @Transactional(propagation = Propagation.REQUIRED)
  public Boolean sendUpdate(WmsStockCheck bo) {
    validEntityBeforeSave(bo);
    return baseMapper.updateById(bo) > 0;
  }
  /**
   * 库存盘点 执行
   */
  @Transactional(propagation = Propagation.REQUIRED)
  public int setUpdateByBo(WmsStockCheck bo) {
    validEntityBeforeSave(bo);
    //  改修stock库存数据
    WmsStockCheckLine lineBo = new WmsStockCheckLine();
    lineBo.setId(bo.getId());
    List<WmsStockCheckLine> allCheckLine = lineMapper.selectStockCheckLine(lineBo);
    WmsStock stockLine = new WmsStock();
      for (WmsStockCheckLine line : allCheckLine) {
        if (line.getCheckQuantity()==null){
          return -1;
        }
        stockService.updateStock(stockLine,line);
        WmsStockLog wmsStockLog = getWmsStockLog(bo, line);
        wmsStockLogService.insertByBo(wmsStockLog);
      }
    bo.setStatus("0");
    baseMapper.updateById(bo);
    return R.SUCCESS;
  }

  @NotNull
  private static WmsStockLog getWmsStockLog(WmsStockCheck bo, WmsStockCheckLine line) {
    WmsStockLog wmsStockLog = new WmsStockLog();
    wmsStockLog.setTypeId(line.getBeforeQuantity() - line.getCheckQuantity() > 0 ? 42L : 43L);
    wmsStockLog.setProductId(line.getProductId());
    wmsStockLog.setMeasureUnit(line.getMeasureUnit());
    wmsStockLog.setBatchCode(line.getBatchCode());
    wmsStockLog.setOrderId(bo.getId());
    wmsStockLog.setWarehouseId(bo.getWarehouseId());
    wmsStockLog.setQuantityBefore(line.getBeforeQuantity());
    wmsStockLog.setQuantityAfter(line.getCheckQuantity());
    wmsStockLog.setRemark(bo.getRemark());
    wmsStockLog.setCreateDept(bo.getCreateDept());
    wmsStockLog.setCreateBy(bo.getCreateBy());
    return wmsStockLog;
  }

  /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(WmsStockCheck entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除库存盘点
     */
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
      //  删除子表
        lineMapper.deleteBatchIds(ids);
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
